/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If 
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 * PARTICULAR PURPOSE.
 * ***************************************************************************/



#if !defined(AFX_PGLDATA_H__27999160_EDC9_4EB8_8296_A72DE81BC0E4__INCLUDED_)
#define AFX_PGLDATA_H__27999160_EDC9_4EB8_8296_A72DE81BC0E4__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <pgl/algotools/Singleton.h>
#include <pgl/core/PGLArchive.h>

/*!
	\defgroup PGLDataGroup Data handling
\ingroup PGLCoreGroup
*/


/* \define PGL_RUNTIME_CLASS

	Macro to use with IsKindOf. Example of use:
\code
	if ( pData->IsKindOf(PGL_RUNTIME_CLASS( CPGLVectorF ) ))
	{
		...
	}

  \ingroup PGLDataGroup
*/
#define PGL_RUNTIME_CLASS( className ) #className


/*! \brief Base class for all data objects used in PGL

	This class, directly inherited from CVectorF, declares the functions that a data object has to implement.

  \ingroup PGLDataGroup
*/
class PGLCORE_EXT_CLASS CPGLData : public gfxinterface::CVectorF, public CPGLNode
{
public:
	typedef boost::shared_ptr< CPGLData > DataPtr; 
	//! \name Virtual functions
	//@{
	CPGLData(){};
	//! returns a copy allocated on the heap of the object. The user must handle memory cleaning.
	virtual DataPtr Clone()const = 0;
	//! returns the class name
	virtual LPCTSTR GetClassName() const = 0;
	//! true if the object corresponds to the class
	virtual bool IsKindOf(LPCTSTR szClassName) const	{  return (_tcscmp( GetClassName(), szClassName ) == 0);};
	//! returns true if this data type can be loaded,
	virtual bool IsLoadable() const = 0;
	//! returns true if this object can be stored
	virtual bool IsStorable() const = 0;
	//! Serializes to an xml archive
	virtual void SerializeXML(CPGLArchive& ar) = 0;
	//@}

protected:
	CMutex m_mutex;
};

PGL_DECLARE_SMARTPTR( CPGLData );

#ifndef PGL_DECLARE_DATA_TYPE
#define PGL_DECLARE_DATA_TYPE( className, baseClass, bLoadable, bStorable) \
	public:\
	static CPGLDataPtr className::GetEmpty ## className ()	{	return CPGLDataPtr(new className);};\
	CPGLDataPtr Clone() const								{	return CPGLDataPtr(new className(*this));}; \
	void SerializeXML(CPGLArchive& ar); \
	bool IsLoadable() const				{	return bLoadable;}; \
	bool IsStorable() const				{	return bStorable;}; \
	LPCTSTR GetClassName() const				{	return _T( #className );}; \
	bool IsKindOf(LPCTSTR szClassName) const	{	if (_tcscmp( GetClassName(), szClassName ) == 0) return true;\
													else return baseClass::IsKindOf( szClassName );};
#endif

#ifndef PGL_SERIALIZE_LOAD_DATA
#define PGL_SERIALIZE_LOAD_DATA( strPos , strName , pData ) \
xml.ResetChildPos(); \
if (xml.FindChildElem(_T( #strName ))) \
{ \
	xml.IntoElem(); \
	xml.ResetChildPos(); \
	xml.SavePos( strPos ); \
	if (xml.FindChildElem()) \
	{ \
		CPGLDataPtr pDataClone = CPGLDataPtr( pgl::CDataRegistrySingleton::GetData( xml.GetChildTagName() ) ); \
		if (pDataClone) \
		{ \
			if ( (ar.IsStoring() && pDataClone->IsStorable()) || (ar.IsLoading() && pDataClone->IsLoadable() )) \
			{ \
				pData = pDataClone; \
				xml.RestorePos( strPos ); \
				pData->SerializeXML(ar); \
			} \
		} \
	} \
	xml.OutOfElem(); \
} 
#endif PGL_SERIALIZE_LOAD_DATA

#endif // !defined(AFX_PGLDATA_H__27999160_EDC9_4EB8_8296_A72DE81BC0E4__INCLUDED_)
